package cn.moukou.tongji.ihealth.doctor.controller;

import cn.moukou.tongji.ihealth.core.bean.Resp;
import cn.moukou.tongji.ihealth.doctor.dao.CaseRecordFileMapper;
import cn.moukou.tongji.ihealth.doctor.pojo.*;
import cn.moukou.tongji.ihealth.doctor.service.*;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PolicyConditions;
import com.baomidou.mybatisplus.extension.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Date;
import java.util.*;


@RestController
@RequestMapping("/ihealth/doctor")
public class ApiController {

    @Autowired(required = false)
    OSS ossClient;

    @Value("${spring.cloud.alicloud.access-key}")
    String accessId;

    @Value("${spring.cloud.alicloud.secret-key}")
    String secretKey;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    String bucket;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    String endpoint;

    @Autowired
    CaseRecordService caseRecordService;

    @Autowired
    DoctorScheduleService scheduleService;

    @Autowired
    PatientReserveService reserveService;

    @Autowired
    ImageService imageService;

    @Autowired
    CaseRecordFileService caseRecordFileService;

    @GetMapping("/ping")
    public String ping() {
        return "pong";
    }

    @GetMapping("/oss/policy")
    public Map<String , String> ossPolicy() {
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        String dir = "ihealth/"; // 用户上传文件时指定的前缀。

        try {
            long expireTime = 300;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            java.util.Date expiration = new java.util.Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            return respMap;

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return null;
    }

    @PostMapping("/case-record/add")
    public Resp<String> addCaseRecord(@RequestParam("pid") String pid,
                                      @RequestParam("patientName") String patientName, @RequestParam("patientAge") int patientAge, @RequestParam("patientSex") String patientSex,
                                      @RequestParam("patientPhoneNumber") String patientPhoneNumber,
                                      @RequestParam("did") String did,
                                      @RequestParam("doctorName") String doctorName,
                                      @RequestParam("caseDescription") String caseDescription,
                                      @RequestParam("solutionDescription") String solutionDescription
                                      ) {
        if (caseRecordService.addOneCaseRecord(pid, patientName, patientAge, patientSex, patientPhoneNumber,
                did, doctorName, caseDescription, solutionDescription)>0) {
            return Resp.ok("创建成功");
        } else {
            return Resp.fail("病例创建失败");
        }
    }

    @GetMapping("/case-record/get")
    public Resp<ArrayList<CaseRecord>> getCaseRecords(@RequestParam("pid") String pid) {
        ArrayList<CaseRecord> caseRecords = caseRecordService.getCaseRecordsByPid(pid);
        return Resp.ok(caseRecords);
    }

    @GetMapping("/case-record/one/get")
    public Resp<Object> getOneCaseRecord(@RequestParam("cid") Long id) {
        Map<String, Object> resMap = new HashMap<>();
        CaseRecord caseRecord = caseRecordService.getOneCaseRecord(id);
        resMap.put("caseRecordInfo", caseRecord);
        List<CaseRecordFile> caseRecordFiles = caseRecordFileService.getFilesByCid(id);
        resMap.put("attachFiles", caseRecordFiles);
        return Resp.ok(resMap);
    }

    @PostMapping("/case-record/one/update")
    public Resp<Object> updateOneCaseRecord(@RequestParam("id") Long id,
                                            @RequestParam("pid") String pid,
                                            @RequestParam("patientName") String patientName, @RequestParam("patientAge") int patientAge, @RequestParam("patientSex") String patientSex,
                                            @RequestParam("patientPhoneNumber") String patientPhoneNumber,
                                            @RequestParam("caseDescription") String caseDescription,
                                            @RequestParam("solutionDescription") String solutionDescription) {
        int flag = caseRecordService.updateOneCaseRecord(id, pid, patientName, patientAge, patientSex, patientPhoneNumber, caseDescription, solutionDescription);
        if(flag>0) {
            return Resp.ok("修改成功");
        } else {
            return Resp.fail("修改失败");
        }
    }

    @GetMapping("/workday/get")
    public Resp<List<DoctorSchedule>> getMyWorkDate(@RequestParam("did") String did) {
        List<DoctorSchedule> schedules = scheduleService.getMyWorkDay(did);
        return Resp.ok(schedules);
    }

    @GetMapping("/reserve/day/get")
    public Resp<Object> getAllReserves(@RequestParam("date") Date date, @RequestParam("did") String did) {

        Map<String, Object> resMap = new HashMap<>();
        List<PatientReserve> freeReserves = reserveService.getFreeReservesByDate(date);
        List<PatientReserve> myReserves = reserveService.getMyReservesByDate(date, did);

        resMap.put("freeReserves", freeReserves);
        resMap.put("myReserves", myReserves);
        return Resp.ok(resMap);
    }

    @GetMapping("/reserve/detail")
    public Resp<Object> getReserveDetail(@RequestParam("id") Long id) {
        PatientReserve reserve = new PatientReserve();
        reserve = reserveService.getOne(id);
        return Resp.ok(reserve);
    }

    @PostMapping("/reserve/receive")
    public Resp<Object> receiveReserve(@RequestParam("rid") Long rid, @RequestParam("did") String did) {
        if(reserveService.receiveReserve(rid, did)>0) {
            return Resp.ok("接受成功");
        } else {
            return Resp.fail("接受失败，系统错误");
        }
    }

    @PostMapping("/reserve/cancel")
    public Resp<Object> cancelReserve(@RequestParam("rid") Long rid) {
        if(reserveService.cancelReserve(rid)>0) {
            return Resp.ok("取消成功");
        } else {
            return Resp.fail("取消失败，系统错误");
        }
    }

    @PostMapping("/image/url/save")
    public Resp<Object> saveImageUrl(@RequestParam("key") String key, @RequestParam("label") int label) {
        String url ="https://" + bucket + "." + endpoint + "/" + key;
        if(imageService.saveImageUrl(url, label)>0) {
            return Resp.ok("保存成功");
        } else {
            return Resp.fail("保存失败");
        }
    }

    @GetMapping("/image/rand/get")
    public Resp<Object> getRandImageList() {
        List<Image> images = imageService.randSelect();
        return Resp.ok(images);
    }

    @PostMapping("/case-record/file/key/save")
    public Resp<Object> addCaseRecordFile(@RequestParam("cid") Long cid, @RequestParam("did") String did,
                                          @RequestParam("filepath") String filepath, @RequestParam("filename") String filename) {
        if(caseRecordFileService.insertOne(cid, did, filepath, filename)>0) {
            return Resp.ok("添加成功");
        } else {
            return Resp.fail("添加失败");
        }
    }

    @GetMapping("/case-record/file/download")
    public void caseRecordFileDownload(@RequestParam("cid") String cid, @RequestParam("filename") String filename,
                                       HttpServletResponse response) throws UnsupportedEncodingException {


        response.setContentType("text/html;charset=utf-8");
        response.setContentType("application/force-download");// 设置强制下载不打开
        response.addHeader("Content-Disposition",
                "attachment;fileName=" +  URLEncoder.encode(filename,  "utf-8"));// 设置文件名

        BufferedInputStream bis = null;
        OutputStream os = null;

        try {
            System.out.println("case-record/" + cid + "/" + filename);
            OSSObject ossObject = ossClient.getObject("tongji-ihealth", "ihealth/case-record/" + cid + "/" + filename);
            bis = new BufferedInputStream(ossObject.getObjectContent());
            os = response.getOutputStream();

            byte[] buffer = new byte[1024];
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(bis!=null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            ossClient.shutdown();
        }

    }

    @PostMapping("/case-record/file/delete")
    public Resp<Object> caseRecordFileDownload(@RequestParam("filepath") String filepath) {

        System.out.println(filepath);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, secretKey);
        ossClient.deleteObject(bucket, filepath);

        // 关闭OSSClient。
        ossClient.shutdown();

        if(caseRecordFileService.deleteOne(filepath)>0) {
            return Resp.ok("删除成功");
        } else {
            return Resp.fail("服务器错误，删除失败");
        }

    }

}
